/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行，false 表非立即执行
 * 所谓防抖，就是指触发事件后在 n 秒内函数只能执行一次，如果在 n 秒内又触发了事件，则会重新计算函数执行时间。
 */
export function debounce(func, wait, immediate) {
  let timeout;
  return function () {
    let _this = this;
    let args = arguments;
    if (timeout) clearTimeout(timeout);
    if (immediate) {
      var callNow = !timeout;
      timeout = setTimeout(() => {
        timeout = null;
      }, wait);
      if (callNow) func.apply(_this, args);
    } else timeout = setTimeout(function () {
      func.apply(_this, args);
    }, wait);
  };
}
/**
 * @desc 函数节流 连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param options
 *  ptions.begin === true就第一触发事件就立刻会执行回调函数 时间戳
 * options.end === true事件停止触发后也会执行一次该回调函数 定时器
 */
export function throttle(func, wait, options = {}) {
  let timeout;
  let previous = 0;
  return function () {
    let now = Number(new Date());
    let remain = wait - (now - previous);
    if (remain < 0) {
      if (previous === 0 && !options.begin) {
        previous = now;
        return;
      }
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }

      previous = now;
      func.call(this, arguments);
    } else if (!timeout && options.end) timeout = setTimeout(() => {
      func.call(this, arguments);
      timeout = null;
    }, wait);
  };
}
/**
 * @desc 睡眠
 * @param ms 毫秒
 * 睡眠
 */
export const timeout = async (ms) => {
  await new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
};
/**
 * @desc 创建动画圆球
 * @param ms
 * 睡眠
 */
export function createBalls() {
  let balls = [];
  for (let i = 0; i < 7; i++) balls.push({
    'show': false
  });
  return balls;
}
/**
 * @desc 补全
 * @param data 时间戳
 * @param fmt 格式
 */
function padLeftZero(str) {
  return ('00' + str).substr(str.length);
}

/**
 * @desc 格式化日期
 * @param data 时间戳
 * @param fmt 格式
 */
export function formatDate(date, fmt) {
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (String(date.getFullYear())).substr(4 - RegExp.$1.length));
  let o = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds()
  };
  for (let k in o)
    // eslint-disable-next-line nonblock-statement-body-position
    if (new RegExp(`(${k})`).test(fmt)) {
      let str = String(o[k]);
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
    }

  return fmt;
}
/**
 * @desc 解析url参数
 * @example ?id=12345&a=b
 * @return Object {id:12345,a:b}
 */
export function urlParse() {
  let url = window.location.search;
  let obj = {};
  let reg = /[?&][^?&]+=[^?&]+/g;
  let arr = url.match(reg);
  // ['?id=12345', '&a=b']
  if (arr) arr.forEach((item) => {
    let tempArr = item.substring(1).split('=');
    let key = decodeURIComponent(tempArr[0]);
    let val = decodeURIComponent(tempArr[1]);
    obj[key] = val;
  });
  return obj;
}
